### **Chrome Extensions: Changes from Manifest V2 to V3** Chrome **Manifest V3 (MV3)** introduced significant security, performance, and privacy improvements, but also removed some key features from **Manifest V2 (MV2)**. Here’s a breakdown of what was **removed**, what was **added**, and what was **changed**: --- ## **🚫 Features Removed in Manifest V3** ### **1. Background Pages → Replaced with Service Workers** - **MV2:** Extensions used **persistent background pages** (`background.html` or a background script). - **MV3:** **Service workers** are now required instead. - Service workers **only run when needed**, reducing resource usage. - They **cannot use `setTimeout()` or long-running connections**. - `chrome.runtime.getBackgroundPage()` is no longer available. ✅ **Alternative: Use event-driven service workers.** ```json { "background": { "service_worker": "background.js" } } ``` --- ### **2. `chrome.browserAction` & `chrome.pageAction` → Merged into `chrome.action`** - **MV2:** Used `browserAction` (for global actions) and `pageAction` (for per-tab actions). - **MV3:** Both are merged into `chrome.action`. ✅ **Example:** ```json { "action": { "default_icon": "icon.png", "default_popup": "popup.html" } } ``` --- ### **3. `chrome.extension.getBackgroundPage()` Removed** - **MV2:** Allowed retrieving the background page. - **MV3:** Not available due to service workers. ✅ **Alternative:** Use `chrome.runtime.sendMessage()`. --- ### **4. `content_security_policy` Changes** - **MV2:** Allowed `unsafe-inline` in `style-src` and `script-src`. - **MV3:** **Removes `'unsafe-inline'` and `'unsafe-eval'`**. - No inline scripts (``)... because it's no longer covered under unsafe-eval and unsafe inline and will error in console. Use js file instead. - No inline event handlers (`onclick=""` won't work). - No `eval()` or `setTimeout("code", delay)`. - Reworded: unsafe-inline no longer supported in v3 ``` "content_security_policy": { "extension_pages": style-src 'self' 'unsafe-inline';" ``` - This policy in v2 disallows external css files and allows inline style `
{ console.log("Checking for updates..."); }); ``` --- ### **2. `chrome.scripting` API for Content Scripts** - **MV2:** Content scripts were managed via `tabs.executeScript()`. - **MV3:** New `chrome.scripting.executeScript()` API. ✅ **Example: Injecting a script dynamically** ```javascript chrome.scripting.executeScript({ target: { tabId: someTabId }, files: ["content-script.js"] }); ``` --- ### **3. Separation of API and Hosting Permissions** In Manifest V2, everything was lumped together under `permissions`, which led to **overly broad permissions**. V3 splits them to encourage **least privilege**: - `permissions`: Core Chrome features - `host_permissions`: Access to specific sites Chrome can now also **request host permissions at runtime** (via the **optional permissions** model), which gives users more control. Example: ``` "permissions": [ "storage", "tabs", "scripting", "notifications" ], "host_permissions": [ "https://*.example.com/*", "*://*.google.com/*" ] ``` --- ### 4. Improved Security & Permissions Model** - Extensions must **declare all host permissions explicitly** in `manifest.json` (`activeTab` no longer allows access to all sites). - **Optional permissions** can now be requested dynamically. ✅ **Example: Requesting host permissions at runtime** ```javascript chrome.permissions.request({ permissions: ["tabs"], origins: ["https://example.com/"] }); ``` --- ### **5. New `declarativeNetRequest` API** - **MV3's replacement for `webRequest` API**. - Predefined rules in `rules.json` control network requests. - Less flexible but more performant. ✅ **Example: Blocking ads** ```json [ { "id": 1, "priority": 1, "action": { "type": "block" }, "condition": { "urlFilter": "ads.example.com", "resourceTypes": ["script"] } } ] ``` --- ### **6. New Host Permission Model** - In **MV2**, declaring `"host_permissions"` granted immediate access. - In **MV3**, `"host_permissions"` must be **explicitly requested at runtime**. ✅ **Example:** ```json { "host_permissions": ["https://example.com/"] } ``` --- ### **7. All scripts must be local in Manifest V3** **All JavaScript must be included in the extension package itself.** - ❌ Wildcards (`*`) or remote domains are **not allowed** for `script-src` in Chrome Extension CSP. - ✅ `'self'` is permitted. Wildcards like `*` **were allowed** in `script-src` and `style-src`,  in V2, although **not recommended**. In V3, it’s completely not allowed. --- ### **8. `offscreen` API for Hidden Background Work** - Allows running tasks like audio playback without a visible tab. - Used when service workers **cannot handle background tasks**. ✅ **Example: Create an offscreen document** ```javascript chrome.offscreen.createDocument({ url: "offscreen.html", reasons: ["AUDIO_PLAYBACK"], justification: "Playing background music" }); ``` --- ## **📌 Summary of Key Differences** | Feature | Manifest V2 | Manifest V3 | | ---------------------------------------- | ---------------------------------------- | -------------------------------------------------------- | | **Background Scripts** | Persistent `background.js` | **Service workers** (non-persistent) | | **Long-running Background Tasks** | Persistent pages | **Use `offscreen` API** or `alarms` | | **`browserAction` / `pageAction`** | Two separate APIs | ✅ **Merged into `chrome.action`** | | **`chrome.runtime.getBackgroundPage()`** | ✅ Available | 🚫 **Removed** (use messaging instead) | | **Inline Scripts & Styles** | ✅ Allowed (`unsafe-inline`) | 🚫 **Blocked** (Use external files only) | | **Blocking `webRequest` API** | ✅ Allowed | 🚫 **Replaced with `declarativeNetRequest`** | | **`chrome.runtime.onSuspend`** | ✅ Available | 🚫 **Removed** (service workers suspend automatically) | | **Executing Scripts** | `tabs.executeScript()` | 🚀 **Use `chrome.scripting.executeScript()`** | | **Split Permissions Model** | All in `permissions` | ✅ **Split into `permissions` + `host_permissions`** | | **Permissions Model** | Implicit host permissions | 🚫 **Must be declared explicitly** | | **Event Handling** | Inline handlers (`onclick=""`) allowed | 🚫 **Use `addEventListener()` instead** | | **All Scripts Must Be Local** | Remote scripts allowed (not recommended) | 🚫 **Only local scripts allowed** | | **`offscreen` API** | ❌ Not available | ✅ **New API for hidden background tasks** | | **Dynamic Host Permissions** | ❌ Not supported | ✅ **Can request at runtime via `permissions.request()`** | ✅ **Pros of Manifest V3** - **Better performance** (less memory usage). - **Stronger security** (no inline scripts, fewer attack vectors). - **More efficient request handling** (`declarativeNetRequest`). - **More granular permissions control**. ⚠️ **Cons of Manifest V3** - **Service workers expire when idle** (requires event-driven coding). - **Less flexible network request modification**. - **No inline scripts or styles** (requires workarounds). --- ## **Final Thoughts** - **New extensions must use MV3** (MV2 is no longer supported in Chrome Web Store). - Existing MV2 extensions **will stop working by June 2025**. - If your extension uses **persistent background scripts, blocking `webRequest`, or inline scripts**, you **must migrate**.